<template>
	<view class="vi_progress" :style="mainStyle">
		<view class="vi_progress_content">
			<view class="vi_progress_bg">
				<vi-style-controller
					:compName="tipSetting.open && tipsInside=='plain'?'progressInside':'progress'"
					control="background"
					type="default"
					:color="bgColor"
					:size="setting.size"
					:height="height"
					:radius="setting.radius"
					active></vi-style-controller>
			</view>
			<view class="vi_progress_bar" :style="barStyle">
				<vi-style-controller
					:compName="tipSetting.open && tipsInside=='plain'?'progressInside':'progress'"
					control="background"
					:type="setting.type"
					:color="barColor"
					:size="setting.size"
					:height="height"
					:radius="setting.radius"
					active></vi-style-controller>
				<view class="vi_progress_tipsIn_plain">
					<vi-style-controller v-if="tipSetting.open && tipsInside=='plain'"
						:type="inValue>setting.tipsOverflow?'primary':''"
						:textColor="textColor"
						backgroundColor="transparent"
						:width="tipSetting.icon?'1.4em':''"
						height="1.4em"
						inline
						active>
						<view class="vi_progress_tipsIn_text">
							<view v-if="tipSetting.icon" class="iconfont" :class="tipSetting.icon"></view>
							<view v-else>{{tipSetting.value}}</view>
						</view>
					</vi-style-controller>
				</view>
			</view>
			<view class="vi_progress_tipsIn" :style="tipsInStype" v-if="tipSetting.open && tipsInside==true">
				<vi-style-controller
					:type="setting.type"
					:color="barColor"
					:textColor="textColor"
					:width="tipSetting.icon?'1.4em':''"
					height="1.4em"
					:radius="setting.tipsRadius"
					active>
					<view class="vi_progress_tipsIn_text">
						<view v-if="tipSetting.icon" class="iconfont" :class="tipSetting.icon"></view>
						<view v-else>{{tipSetting.value}}</view>
					</view>
				</vi-style-controller>
			</view>
		</view>
		<view class="vi_progress_tipsOut" :style="{'width':tipSetting.width}" v-if="tipSetting.open && !tipsInside">
			<vi-style-controller
				:type="tipSetting.type"
				:color="tipSetting.color"
				:textColor="tipSetting.textColor"
				:plain="!tipSetting.icon||tipSetting.plain"
				:width="tipSetting.icon?'1.4em':''"
				:height="tipSetting.icon?'1.4em':''"
				:radius="tipSetting.radius||''"
				active>
				<view v-if="tipSetting.icon" class="iconfont" :class="tipSetting.icon"></view>
				<view v-else>{{tipSetting.value}}</view>
			</vi-style-controller>
		</view>
	</view>
</template>

<script>
	export default{
		name:"viProgress",
		options:{//样式穿透，微信须设置
			styleIsolation: "shared"
		},
		props:{
			type:{
				type:[String,null],
				default:null
			},
			//颜色值，可自定义
			// [
			// 	{value:"颜色值",rate:进度值}
			// ]
			color:{
				type:[String,Array,null],
				default:""
			},
			textColor:{
				type:[String,null],
				default:""
			},
			//预设尺寸,sm、md、lg
			size:{
				type:[String,null],
				default:null
			},
			//圆角，自定义单位，circle圆形，square方形
			radius:{
				type:[String,Number,null],
				default:null
			},
			//进度条高
			height:{
				type:[String,Number,null],
				default:""
			},
			value:{
				type:[Number,String,null],
				default:0
			},
			//固定多少位小数
			decimals:{
				type:[Number,null],
				default:0
			},
			//数值显示。可自定义
			// [
			// 	{
			//	value:	显示值
			//	rate:	进度值
			//	icon:	图标名，优先
			//	plain:	镂空(图标类型有效，文字固定镂空)
			//	type:	主题色
			//	color:	自定义颜色
			//	textColor:	固定文字色
			//	}
			// ]
			tips:{
				type:[Boolean,Array,null],
				default:null
			},
			//标签显示置于内部，plain为内部镂空
			tipsInside:{
				type:[Boolean,String,null],
				default:false
			},
			tipsOverflow:{
				type:[Number,null],
				default:null
			},
			//标签跟随进度条主题色，外部标签有效。图标类型默认跟随
			tipsColorFollow:{
				type:[Boolean,null],
				default:false
			},
			//标签圆角，内部标签有效。标签高1.4em
			tipsRadius:{
				type:[String,Number,null],
				default:null
			},
			bgColor:{
				type:[String,null],
				default:null
			}
		},
		data(){
			return {
				squareRatio:0.2,
				inValue:0,
			}
		},
		computed:{
			setting(){
				return {
					type: this.$api.isDefined(this.type)? this.type :"primary",
					radius: this.$api.isDefined(this.radius)? this.radius :"circle",
					tipsRadius: this.$api.isDefined(this.tipsRadius)? this.tipsRadius :"0.7em",
					size: this.$api.isDefined(this.size)? this.size :"md",
					tips: this.$api.isDefined(this.tips)? this.tips :true,
					tipsOverflow: this.$api.isValue(this.tipsOverflow)?this.tipsOverflow :0,
					bgColor: this.$api.isDefined(this.bgColor)? this.bgColor :"#eee",
				}
			},
			//进度条颜色
			barColor(){
				let color = this.color;
				if(!color){
					return ""
				}else if(this.$api.isString(color)){
					return color
				}else if(color.length){//数组类型，动态颜色
					let res;
					for(let item of color){
						if(this.inValue >= item.rate){
							res = item.color
						}
					}
					return res
				}
				return ""
			},
			barStyle(){
				let res = {
					"width": this.inValue +"%"
				}
				return this.$api.objToStr(res)
			},
			tipsInStype(){
				return `left:${this.inValue}%;transform: translate(-${this.inValue}%,-50%);`
			},
			tipSetting(){
				let tips = this.setting.tips,
					res ={
						open: !!tips,
						value: this.inValue.toFixed(this.decimals||0) +"%",
					};
				//自定义标签
				if(this.$api.isArray(tips)){
					for(let item of tips){
						if(this.inValue >= item.rate){
							Object.assign(res,{
								icon: item.icon,
								value: item.hasOwnProperty("value")? item.value||"" :this.inValue.toFixed(this.decimals||0) +"%",
								type: item.hasOwnProperty("type")? item.type :(this.tipsColorFollow? this.setting.type:""),
								color: item.hasOwnProperty("color")? item.color :(this.tipsColorFollow? this.barColor:""),
								textColor: item.hasOwnProperty("textColor")? item.textColor :(this.tipsColorFollow? this.textColor:""),
								plain: item.hasOwnProperty("plain")? item.plain :true,
								radius: item.hasOwnProperty("radius")? item.radius :"circle"
							})
						}
					}
				}
				if(res.icon){
					res["width"] = "1.5em";
				}else if(res.value && res.value.includes("%")){
					res["width"] = this.decimals? (7+ this.decimals)/2 +"em" :"3em"
				}else{
					res["width"] = res.value.length +"em"
				}
				return res
			},
			mainStyle(){
				if(this.tipSetting.open && this.tipsInside==true){
					return `font-size: 85%;height:1.4em;`
				}
			},
		},
		methods:{
			
		},
		watch:{
			"value":{
				immediate:true,
				handler(newVal){
					let val = Number(newVal) ||0;
					this.inValue = val>100? 100: (val<0? 0:val);
				}
			},
		}
	}
</script>

<style lang="scss">
.vi_progress{
	position: relative;
	display: flex;
	align-items: center;
	.vi_progress_content{
		flex-grow: 1;
		position: relative;
	}
	.vi_progress_bg{
		position: absolute;
		width: 100%;
		height: 100%;
		z-index: 1;
	}
	.vi_progress_bar{
		position: relative;
		width: 0;
		height: 100%;
		z-index: 2;
		transition: 0.3s;
		text-align: right;
	}
	.vi_progress_tipsIn{
		position: absolute;
		top: 50%;
		z-index: 3;
		transition: 0.3s;
	}
	.vi_progress_tipsIn_plain{
		position: absolute;
		top: 50%;
		width: 100%;
		transform: translateY(-50%);
		text-align: right;
		font-size: 85%;
	}
	.vi_progress_tipsIn_text{
		padding: 0 0.5em;
		white-space: nowrap;
	}
	.vi_progress_tipsOut{
		margin-left: 0.75em;
	}
}
.vi_progress .vi_progress_tipsIn /deep/ .vi_styleController,
.vi_progress .vi_progress_tipsOut /deep/ .vi_styleController{
	transition: initial;
}
</style>